Hanging Chain Problem

We will solve a reformulated version of the Hanging Chain Problem from the Constrained Optimization Problem Set.

Problem Statement and Model

In this problem, we seek to minimize the potential energy of a chain of length $L$ suspended between points $a$ and $b$. The potential energy constrained by length is represented by:

\[\begin{gathered} \int_0^1 x(1 + (x')^2)^{1/2} \, dt \end{gathered}\]

Our optimization problem is defined as follows:

\[\begin{aligned} &&\min_{x,u} x_2(t_f)\\ &&\text{s.t.} &&& \quad \dot{x}_1= u\\ &&&&&\dot{x}_2 = x_1(1+u^2)^{1/2}\\ &&&&&\dot{x}_3 = (1+u^2)^{1/2}\\ &&&&&x(t_0) = (a,0,0)^T\\ &&&&&x_1(t_f) = b\\ &&&&&x_3(t_f) = L\\ &&&&&x(t) \in [0,10]\\ &&&&&u(t) \in [-10,20]\\ \end{aligned}\]

Model Definition

First we must import $InfiniteOpt$ and other packages.

using InfiniteOpt, Ipopt, Plots;

Next we specify an array of initial conditions as well as problem variables.

a, b, L = 1, 3, 4
x0 = [a, 0, 0]
xtf = [b, NaN, L];

We initialize the infinite model and opt to use the Ipopt solver

m = InfiniteModel(Ipopt.Optimizer);

t is specified as $\ t \in [0,1]$. The bounds are arbitrary for this problem:

@infinite_parameter(m, t in [0,1], num_supports = 100);

Now let's specify variables. $u$ is our controller variable.

@variable(m, 0 <= x[1:3] <= 10, Infinite(t))
@variable(m, -10 <= u <= 20, Infinite(t));

Specifying the objective to minimize kinetic energy at the final time:

@objective(m, Min, x[2](1));

Define the ODEs which serve as our system model.

@constraint(m, ∂(x[1],t) == u)
@constraint(m, ∂(x[2],t) == x[1] * (1 + u^2)^(1/2))
@constraint(m, ∂(x[3],t) == (1 + u^2)^(1/2));

Set our inital and final conditions.

@constraint(m, [i in 1:3], x[i](0) == x0[i])
@constraint(m, x[1](1) == xtf[1])
@constraint(m, x[3](1) == xtf[3]);

Problem Solution

Optimize the model:

optimize!(m)
This is Ipopt version 3.14.4, running with linear solver MUMPS 5.4.1.

Number of nonzeros in equality constraint Jacobian...:     1596
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:      400

Total number of variables............................:      700
                     variables with only lower bounds:        0
                variables with lower and upper bounds:      400
                     variables with only upper bounds:        0
Total number of equality constraints.................:      602
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0  9.9999900e-03 3.99e+00 1.00e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  8.6845875e-02 1.95e+01 1.61e+04  -1.0 6.57e+01    -  2.56e-03 3.02e-01f  1
   2  1.7965356e-01 1.87e+01 2.25e+04  -1.0 5.31e+01   4.0 3.21e-02 4.23e-02h  1
   3  1.8137048e-01 1.87e+01 2.33e+04  -1.0 4.73e+01   4.4 6.31e-02 6.68e-04h  1
   4  1.8140295e-01 1.87e+01 1.89e+06  -1.0 4.83e+01   4.9 1.26e-01 1.22e-05h  1
   5  1.9254888e-01 1.86e+01 2.48e+06  -1.0 4.81e+01   4.4 2.04e-01 4.17e-03h  1
   6  2.0905429e-01 1.85e+01 3.64e+06  -1.0 4.86e+01   4.8 1.09e-01 6.07e-03h  1
   7  2.2802793e-01 1.84e+01 3.41e+07  -1.0 4.82e+01   5.2 3.59e-01 6.93e-03h  1
   8  2.8201307e-01 1.80e+01 3.06e+07  -1.0 4.62e+01   4.7 1.02e-01 2.02e-02h  1
   9  3.1317553e-01 1.78e+01 3.47e+07  -1.0 4.47e+01   5.2 2.45e-01 1.13e-02h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10  3.4723467e-01 1.76e+01 4.07e+07  -1.0 4.39e+01   5.6 5.62e-02 1.22e-02h  1
  11  3.8552094e-01 1.73e+01 6.10e+07  -1.0 4.28e+01   6.0 6.34e-02 1.37e-02h  1
  12  4.0843146e-01 1.72e+01 6.02e+07  -1.0 3.93e+01   5.6 7.08e-03 8.64e-03h  1
  13  4.1028640e-01 1.72e+01 1.02e+08  -1.0 3.99e+01   6.0 6.60e-02 6.60e-04h  1
  14  4.3553508e-01 1.70e+01 3.20e+08  -1.0 4.04e+01   6.4 1.31e-01 8.93e-03h  1
  15  4.5808211e-01 1.69e+01 3.20e+08  -1.0 3.81e+01   5.9 2.79e-02 8.08e-03h  1
  16  4.6870391e-01 1.68e+01 3.89e+08  -1.0 3.84e+01   6.4 7.68e-02 3.74e-03h  1
  17  5.1251695e-01 1.66e+01 5.77e+08  -1.0 3.84e+01   6.8 8.31e-02 1.54e-02f  1
  18  5.2292005e-01 1.65e+01 5.69e+08  -1.0 3.52e+01   6.3 1.53e-02 3.70e-03h  1
  19  5.2697033e-01 1.65e+01 6.03e+08  -1.0 3.63e+01   6.7 6.98e-02 1.42e-03h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20  6.1393774e-01 1.60e+01 7.16e+08  -1.0 3.66e+01   7.2 8.66e-02 3.03e-02f  1
  21  7.3213394e-01 1.53e+01 6.54e+08  -1.0 3.40e+01   7.6 6.77e-03 4.09e-02f  1
  22  8.0635655e-01 1.49e+01 6.80e+08  -1.0 3.09e+01   8.0 4.06e-04 2.55e-02f  1
  23  8.5443045e-01 1.47e+01 1.27e+09  -1.0 2.92e+01   8.4 1.25e-03 1.65e-02f  1
  24  8.5472095e-01 1.47e+01 7.25e+08  -1.0 2.70e+01   8.0 4.02e-02 9.99e-05h  1
  25  9.4924730e-01 1.42e+01 1.17e+09  -1.0 2.79e+01   8.4 7.89e-03 3.24e-02f  1
  26  9.7274767e-01 1.41e+01 1.75e+09  -1.0 2.61e+01   8.8 1.73e-05 8.07e-03f  1
  27  9.7893019e-01 1.41e+01 1.74e+09  -1.0 2.48e+01   8.3 7.44e-02 2.13e-03h  1
  28  1.1355863e+00 1.33e+01 2.81e+09  -1.0 2.54e+01   8.8 2.24e-05 5.39e-02f  1
  29  1.1851152e+00 1.31e+01 5.26e+09  -1.0 2.26e+01   9.2 1.46e-03 1.71e-02f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30  1.1875976e+00 1.31e+01 6.54e+09  -1.0 2.07e+01   8.7 5.75e-02 8.61e-04h  1
  31  1.3495034e+00 1.23e+01 1.76e+10  -1.0 2.16e+01   9.1 1.24e-03 5.62e-02f  1
  32  1.4016517e+00 1.21e+01 4.27e+10  -1.0 1.92e+01   9.6 1.85e-04 1.84e-02f  1
  33  1.7460477e+00 1.06e+01 5.77e+10  -1.0 1.75e+01   9.1 1.05e-02 1.22e-01f  1
  34  1.7872628e+00 1.05e+01 9.82e+10  -1.0 1.38e+01   9.5 1.91e-05 1.53e-02f  1
  35  1.8094359e+00 1.04e+01 1.72e+11  -1.0 1.38e+01   9.9 4.00e-05 8.30e-03f  1
  36  4.4588974e+00 6.90e+00 1.58e+12  -1.0 1.32e+01   9.5 4.08e-06 9.90e-01f  1
  37  4.4745421e+00 6.74e+00 1.56e+12  -1.0 6.33e+00   9.9 2.59e-05 2.30e-02f  1
  38  5.1417859e+00 6.94e+00 1.26e+12  -1.0 5.94e+00   9.4 4.03e-05 9.90e-01f  1
  39  5.1719734e+00 4.63e+00 1.06e+13  -1.0 5.68e+00   8.9 4.41e-06 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  40  5.1832741e+00 3.21e-02 4.22e+09  -1.0 4.15e+00    -  1.28e-02 1.00e+00f  1
  41  5.1788574e+00 5.04e-02 3.25e+07  -1.0 3.22e-01    -  9.90e-01 1.00e+00h  1
  42  5.1780818e+00 2.22e+00 4.66e+05  -1.0 4.11e+00    -  9.86e-01 1.00e+00h  1
  43  5.1783273e+00 8.55e-03 3.40e+08  -1.0 1.14e+00   8.4 9.89e-01 1.00e+00h  1
  44  5.1783273e+00 2.01e-07 1.24e+06  -1.0 4.63e-03   8.0 9.90e-01 1.00e+00h  1
  45  5.1783273e+00 3.55e-15 3.25e+00  -1.0 1.05e-07   7.5 9.98e-01 1.00e+00h  1
  46  5.1783273e+00 3.55e-15 2.63e-04  -3.8 2.54e-11   7.0 1.00e+00 1.00e+00h  1
  47  5.1783273e+00 3.55e-15 3.15e-04  -5.7 9.13e-11   6.5 1.00e+00 1.00e+00h  1
  48  5.1783273e+00 3.55e-15 3.15e-04  -5.7 2.74e-10   6.1 1.00e+00 1.00e+00h  1
  49  5.1783273e+00 3.55e-15 3.15e-04  -5.7 8.22e-10   5.6 1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  50  5.1783273e+00 3.55e-15 3.15e-04  -5.7 2.47e-09   5.1 1.00e+00 1.00e+00h  1
  51  5.1783273e+00 3.55e-15 3.15e-04  -5.7 7.40e-09   4.6 1.00e+00 1.00e+00h  1
  52  5.1783273e+00 1.07e-14 3.15e-04  -5.7 2.22e-08   4.2 1.00e+00 1.00e+00h  1
  53  5.1783273e+00 3.55e-15 3.15e-04  -5.7 6.66e-08   3.7 1.00e+00 1.00e+00h  1
  54  5.1783273e+00 3.55e-15 3.15e-04  -5.7 2.00e-07   3.2 1.00e+00 1.00e+00h  1
  55  5.1783273e+00 1.44e-14 3.15e-04  -5.7 5.99e-07   2.7 1.00e+00 1.00e+00h  1
  56  5.1783273e+00 1.30e-13 3.15e-04  -5.7 1.80e-06   2.2 1.00e+00 1.00e+00h  1
  57  5.1783272e+00 1.17e-12 3.15e-04  -5.7 5.39e-06   1.8 1.00e+00 1.00e+00h  1
  58  5.1783270e+00 1.05e-11 3.15e-04  -5.7 1.62e-05   1.3 1.00e+00 1.00e+00h  1
  59  5.1783264e+00 9.48e-11 3.15e-04  -5.7 4.85e-05   0.8 1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  60  5.1783247e+00 8.53e-10 3.15e-04  -5.7 1.46e-04   0.3 1.00e+00 1.00e+00h  1
  61  5.1783196e+00 7.67e-09 3.15e-04  -5.7 4.37e-04  -0.1 1.00e+00 1.00e+00h  1
  62  5.1783044e+00 6.90e-08 3.15e-04  -5.7 1.31e-03  -0.6 1.00e+00 1.00e+00h  1
  63  5.1782586e+00 6.21e-07 3.15e-04  -5.7 3.93e-03  -1.1 1.00e+00 1.00e+00h  1
  64  5.1781215e+00 5.56e-06 3.15e-04  -5.7 1.18e-02  -1.6 1.00e+00 1.00e+00h  1
  65  5.1777132e+00 4.95e-05 3.14e-04  -5.7 3.52e-02  -2.1 1.00e+00 1.00e+00h  1
  66  5.1765147e+00 4.30e-04 3.10e-04  -5.7 1.04e-01  -2.5 1.00e+00 1.00e+00h  1
  67  5.1731373e+00 3.50e-03 3.01e-04  -5.7 3.04e-01  -3.0 1.00e+00 1.00e+00h  1
  68  5.1645970e+00 2.37e-02 2.76e-04  -5.7 8.36e-01  -3.5 1.00e+00 1.00e+00h  1
  69  5.1475112e+00 4.74e-01 4.77e-03  -5.7 2.05e+00  -4.0 1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  70  5.1452517e+00 4.51e-01 4.54e-03  -5.7 2.48e+01  -4.4 2.28e-01 4.96e-02h  1
  71  5.1380143e+00 4.88e-01 4.90e-03  -5.7 2.06e+00  -4.0 1.00e+00 8.22e-01h  1
  72  5.1360582e+00 4.58e-01 4.60e-03  -5.7 2.08e+01  -4.5 9.45e-01 6.32e-02h  1
  73  5.1331707e+00 1.85e-01 1.86e-03  -5.7 2.21e+00  -4.1 1.00e+00 6.12e-01h  1
  74  5.1326171e+00 1.84e-01 1.85e-03  -5.7 2.35e+02  -4.5 6.85e-02 6.33e-03h  1
  75  5.1308394e+00 4.02e-02 3.92e-04  -5.7 1.77e+00  -4.1 1.00e+00 9.71e-01h  1
  76  5.1302551e+00 5.42e-03 1.46e-04  -5.7 7.07e-01  -3.7 1.00e+00 1.00e+00h  1
  77  5.1298845e+00 6.97e-03 1.58e-04  -5.7 3.31e+00  -4.2 1.00e+00 1.48e-01h  1
  78  5.1295821e+00 3.08e-03 9.68e-05  -5.7 5.25e-01  -3.7 1.00e+00 1.00e+00h  1
  79  5.1284729e+00 5.51e-02 3.23e-04  -5.7 2.67e+00  -4.2 1.00e+00 8.74e-01h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  80  5.1286779e+00 1.42e-02 2.37e-04  -5.7 1.08e+00  -3.8 1.00e+00 9.08e-01h  1
  81  5.1281565e+00 2.69e-02 2.80e-04  -5.7 1.19e+00  -4.3 1.00e+00 1.00e+00h  1
  82  5.1278347e+00 3.61e-03 6.35e-05  -5.7 4.37e-01  -3.8 1.00e+00 1.00e+00h  1
  83  5.1273746e+00 2.72e-02 1.52e-04  -5.7 1.92e+00  -4.3 1.00e+00 8.04e-01h  1
  84  5.1271029e+00 3.44e-02 2.83e-04  -5.7 1.41e+01  -4.8 3.52e-01 6.76e-02h  1
  85  5.1271295e+00 3.43e-02 2.15e-03  -5.7 3.49e+01  -4.4 5.23e-01 2.51e-03h  3
  86  5.1270478e+00 2.13e-02 2.84e-06  -5.7 1.60e+00    -  1.00e+00 1.00e+00h  1
  87  5.1270446e+00 4.85e-05 1.49e-07  -5.7 9.34e-02    -  1.00e+00 1.00e+00h  1
  88  5.1270447e+00 2.86e-09 1.48e-11  -5.7 8.71e-04    -  1.00e+00 1.00e+00h  1
  89  5.1270303e+00 1.32e-05 2.99e-02  -8.6 8.46e-03    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  90  5.1270301e+00 1.66e-09 1.67e-11  -8.6 1.11e-04    -  1.00e+00 1.00e+00h  1

Number of Iterations....: 90

                                   (scaled)                 (unscaled)
Objective...............:   5.1270301228511315e+00    5.1270301228511315e+00
Dual infeasibility......:   1.6724968069142987e-11    1.6724968069142987e-11
Constraint violation....:   1.6562617943804980e-09    1.6562617943804980e-09
Variable bound violation:   1.1523690231707695e-41    1.1523690231707695e-41
Complementarity.........:   2.5154832478972195e-09    2.5154832478972195e-09
Overall NLP error.......:   2.5154832478972195e-09    2.5154832478972195e-09


Number of objective function evaluations             = 94
Number of objective gradient evaluations             = 91
Number of equality constraint evaluations            = 94
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 91
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 90
Total seconds in IPOPT                               = 0.491

EXIT: Optimal Solution Found.

Extract the results.

ts = value(t)
u_opt = value(u)
x1_opt = value(x[1])
x2_opt = value(x[2])
x3_opt = value(x[3])
@show(objective_value(m))
p1 = plot(ts, [x1_opt, x2_opt, x3_opt],
    label=["x1" "x2" "x3"],
    title="State Variables")

p2 = plot(ts, u_opt,
    label="u(t)",
    title="Input")
plot(p1, p2, layout=(2,1), size=(800,600));
objective_value(m) = 5.1270301228511315

Maintenance Tests

These are here to ensure this example stays up to date.

using Test
@test termination_status(m) == MOI.LOCALLY_SOLVED
@test has_values(m)
@test u_opt isa Vector{<:Real}
@test x1_opt isa Vector{<:Real}
Test Passed

This page was generated using Literate.jl.